package com.kitty.game.task.service.targetHandler;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.config.GameMap;
import com.kitty.game.config.NPC;
import com.kitty.game.config.TalkSet;
import com.kitty.game.config.TaskSet;
import com.kitty.game.map.service.MapService;
import com.kitty.game.role.model.Role;
import com.kitty.game.school.service.SchoolService;
import com.kitty.game.talk.service.TalkService;
import com.kitty.game.task.model.product.TaskTarget;
import com.kitty.game.task.model.product.TaskTargetPopType;
import com.kitty.game.task.model.product.TaskTargetType;
import com.kitty.game.task.model.product.targetparam.TalkTargetParam;
import com.kitty.game.task.model.user.RoleTask;
import com.kitty.game.task.service.NewTaskService;
import com.kitty.listener.BaseGameEvent;
import com.kitty.listener.event.TalkEndEvent;
import org.nutz.json.Json;
import org.nutz.lang.util.NutMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Component
public class TalkTargetHandler extends TaskTargetHandler {
    Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public void handleEvent(Role role, BaseGameEvent baseGameEvent) {
        TalkEndEvent talkEndEvent = (TalkEndEvent)baseGameEvent;
        NewTaskService taskService = SpringUtils.getBean(NewTaskService.class);

        /**获得对话对应任务*/
        TalkService talkService = SpringUtils.getBean(TalkService.class);
        TalkSet talkSet = talkService.getTalkSet(talkEndEvent.getTalkId(), role);

        /**找不到对应的对话时，则不处理*/
        if (talkSet == null) {return ;}
        logger.trace("处理对话结束事件：talkId: {}", talkSet.getId());

        Integer taskId = taskService.getTaskByTalk(talkSet.getId());
        /**有些对话不是任务触发*/
        if (taskId == null) {return ;}
        TaskSet taskSet = taskService.getTaskSet(taskId, role);
        /**找不到对应的任务时，则不处理*/
        if (taskSet == null) {return ;}
        logger.trace("处理对话结束事件：taskId: {}", taskSet.getId());

        /**获得对话所在任务的目标*/
        TaskTarget taskTarget = getTaskTargetByTalk(taskSet, talkSet);
        logger.trace("处理对话结束事件：任务目标: {}", Json.toJson(taskTarget));


        taskService.updateTargetProgress(role, taskSet, taskTarget);
    }

    /**触发任务对话目标*/
    @Override
    public void triggerNow(Role role, TaskSet taskSet, TaskTarget taskTarget) {
        TalkSet talkSet = getFirstTalkByTaskTarget(role, taskSet, taskTarget);
        SpringUtils.getBean(TalkService.class).popFirstTalk(role, talkSet);
    }

    /**获得任务目标的第1个对话产品数据*/
    private TalkSet getFirstTalkByTaskTarget(Role role, TaskSet taskSet, TaskTarget taskTarget) {
        /**任务目标不是对话时，则返回null*/
        if (!taskTarget.getTaskTargetType().equals(TaskTargetType.TALK)) {return null;}

        List<Integer> talkIds = ((TalkTargetParam)taskTarget.getTaskTargetParam()).getTalkList();
        if (talkIds == null || talkIds.size() == 0) {
            return null;
        }

        /**获取第1个对话产品数据*/
        return SpringUtils.getBean(TalkService.class).getTalkSet(talkIds.get(0), role);
    }

    /**
     * 获得对话所在任务的目标
     * @param taskSet
     * @param talkSet
     * @return
     */
    private TaskTarget getTaskTargetByTalk(TaskSet taskSet, TalkSet talkSet) {
        NewTaskService taskService = SpringUtils.getBean(NewTaskService.class);
        int taskTargetCount = taskSet.getTaskTargetCount();
        for (int i=0; i<taskTargetCount; i++) {
            TaskTarget taskTarget = taskSet.getTaskTargetByIndex(i);
            /**只匹配对话*/
            if (!taskService.isMatchTargetType(taskTarget, TaskTargetType.TALK)) {continue;}

            List<Integer> talkList = ((TalkTargetParam) taskTarget.getTaskTargetParam()).getTalkList();

            if (talkList.contains(talkSet.getId())) {
                return taskTarget;
            }
        }

        return null;
    }

    /***
     * 获得角色任务进入地图需要弹出的对话
     * @param role
     * @param taskTargetPopType
     * @return
     */
    private TalkSet getRoleTaskPopTalk(Role role, TaskTargetPopType taskTargetPopType) {
        RoleTask roleTask = role.getTask();
        Map<Integer, Integer> progressMap = roleTask.getAllAcceptedTaskProgress();

        NewTaskService taskService = SpringUtils.getBean(NewTaskService.class);
        for (Map.Entry<Integer, Integer> entry: progressMap.entrySet()) {
            TaskSet taskSet = taskService.getTaskSet(entry.getKey(), role);
            /**理论上已接取的所有任务都应该能找到任务产品数据，只是防错*/
            if (taskSet == null) {continue;}

            TaskTarget taskTarget = taskSet.getTaskTargetByIndex(entry.getValue());
            /**能找到对应任务目标时*/

            if (taskTarget == null) {continue;}
            /**不能匹配类型时，跳过**/
            if (!taskService.isMatchPopType(taskTarget, taskTargetPopType)) {continue;}

            /**不在指定地图时，跳过*/
            if (!isMatchMap(role, taskTarget)) {continue;}

            /**拿到目标的第1个对话产品数据*/
            TalkSet firstTalk = getFirstTalkByTaskTarget(role, taskSet, taskTarget);
            if (firstTalk != null) {
                return firstTalk;
            }
        }

        return null;
    }


    /**是否匹配对应的地图*/
    public boolean isMatchMap(Role role, TaskTarget taskTarget) {
        int mapId = 0;

        NutMap nutMap = (NutMap)taskTarget.getPopParam();
        int mapType = nutMap.getInt("mapType");
        /**判断不同的地图类型*/
        if (mapType == 1) {
            /**指定的常用地图*/
            mapId = nutMap.getInt("mapId");
        } else if (mapType == 2){
            /**师门山头地图*/
            GameMap outerMap = SpringUtils.getBean(SchoolService.class).getOuterMap(role);
            if (outerMap != null) {
                mapId = outerMap.getId();
            }
        } else if (mapType == 3) {
            /**师门洞府地图*/
            GameMap innerMap = SpringUtils.getBean(SchoolService.class).getInnerMap(role);
            if (innerMap != null) {
                mapId = innerMap.getId();
            }
        }
        MapService mapService = SpringUtils.getBean(MapService.class);
        return mapService.isInMap(role, mapId);
    }

    /**获得当前任务玩家任务当前进度的且匹配NPC的第1个对话*/
    public TalkSet getTalkMatchNpc(Role role, TaskSet taskSet, NPC npc) {
        /**任务标识的NPC是否与传入NPC匹配，不能则返回null*/
        String taskNpcName = taskSet.getNpcName();
        if (!npc.getName().contains(taskNpcName)) {return null;}

        NewTaskService taskService = SpringUtils.getBean(NewTaskService.class);
        TaskTarget doingTaskTarget = taskService.getRoleDoingTaskTarget(role, taskSet);
        /**任务目标都完成时，可能获得null*/
        if (doingTaskTarget == null) {return null;}

        /**允许任务目标是对话，但是没有对话内容的任务，此时直接更新任务目标*/
        if (isNoTalk(doingTaskTarget)) {
            SpringUtils.getBean(NewTaskService.class).updateTargetProgress(role, taskSet, doingTaskTarget);
            return null;
        }

        /**如果当前任务目标不能匹配对应NPC，则如果不是第1个任务目标的话，则拿第1个目标再匹配*/
        if (isTalkMatchNpc(role, doingTaskTarget, npc)) {
            return getFirstTalkByTaskTarget(role, taskSet, doingTaskTarget);
        }

        /**第1个目标的下标为0*/
        int firstTargetIndex = 0;
        int targetProgressIndex = role.getTask().getTargetProgress(taskSet.getId());
        if (targetProgressIndex != firstTargetIndex) {
            doingTaskTarget = taskSet.getTaskTargetByIndex(firstTargetIndex);
            if (isTalkMatchNpc(role, doingTaskTarget, npc)) {
                return getFirstTalkByTaskTarget(role, taskSet, doingTaskTarget);
            }
        }

        return null;
    }

    /**对话任务目标是否没有对话(不需要对话)，是返回true*/
    private boolean isNoTalk(TaskTarget taskTarget) {
        NewTaskService taskService = SpringUtils.getBean(NewTaskService.class);
        if (!taskService.isMatchTargetType(taskTarget, TaskTargetType.TALK)) {return false;}

        /**遍历列表中的对话NPC是否有匹配传入的NPC，有则返回匹配成功*/
        List<Integer> talkList = ((TalkTargetParam) taskTarget.getTaskTargetParam()).getTalkList();
        if (talkList == null || talkList.size() == 0) {
            return true;
        }

        return false;
    }

    /**任务对话是否匹配NPC*/
    private boolean isTalkMatchNpc(Role role, TaskTarget taskTarget, NPC npc) {
        NewTaskService taskService = SpringUtils.getBean(NewTaskService.class);
        if (!taskService.isMatchTargetType(taskTarget, TaskTargetType.TALK)) {return false;}

        /**遍历列表中的对话NPC是否有匹配传入的NPC，有则返回匹配成功*/
        List<Integer> talkList = ((TalkTargetParam) taskTarget.getTaskTargetParam()).getTalkList();
        for (int talkId : talkList) {
            TalkSet talkSet = SpringUtils.getBean(TalkService.class).getTalkSet(talkId, role);

            String talkNpcName = talkSet.getNpcName();
            if (talkNpcName.equals(npc.getName())) {
                return true;
            }
        }


        return false;
    }

    /**弹出 在进入地图时需要弹出的对话*/
    public void popTalkOnEnterMap(Role role) {
        TalkSet talkSet = getRoleTaskPopTalk(role, TaskTargetPopType.ENTER_MAP);
        /**找不到时，则不需要处理*/
        if (talkSet == null) {return ;}


        TalkService talkService = SpringUtils.getBean(TalkService.class);
        talkService.popFirstTalk(role, talkSet);
    }
}
